package com.zuilapsa.jmc.model;

import org.dom4j.*;

public class Property implements HelpInterface {
	private Level parent;

	Element config;

	Element definition;

	public Property(Element definition, String name) {
		this.definition = definition;
		config = getDefaultConfig(getSequenceFromName(name));
	}

	public Property(Element definition, int sequence) {
		this.definition = definition;
		config = getDefaultConfig(sequence);
	}

	public Property(Element definition) {
		this.definition = definition;
		config = getDefaultConfig(-1);
	}

	public Property(Element definition, Element config) {
		this.definition = definition;
		this.config = config;
	}

	public Element getDefaultConfig(int sequence) {
		String name;
		if (sequence >= 0) {
			name = definition.attributeValue("name");
			name = name.replace("{*}", Integer.toString(sequence));
		} else {
			name = getDefName();
		}
		Element el = DocumentFactory.getInstance().createElement(
				definition.getName());
		el.addAttribute("name", name);
		el.addAttribute("value", getDefaultValue());
		return el;
	}

	public String getDefName() {
		return definition.attributeValue("name");
	}

	public String getName() {
		return config.attributeValue("name");
	}

	public void setName(String name) {
		config.addAttribute("name", name);
	}

	public String getValue() {
		return config.attributeValue("value");
	}

	public void setValue(String value) {
		config.addAttribute("value", value);
	}

	public String getDefaultValue() {
		return definition.attributeValue("default");
	}

	public static int getSequenceFromName(String name) {
		// TODO more robust sequence selection
		// String def = getDefName();
		// int i = def.indexOf("{*}");
		// String name = getName();
		// String nameRest = name.substring(i);
		String number = name.replaceAll("\\D", "");
		return Integer.parseInt(number);
	}

	public int getSequence() {
		if (getDefName().contains("{*}")) {
			return getSequenceFromName(getName());
		} else {
			return -1;
		}
	}

	public void setParent(Level parent) {
		this.parent = parent;
	}

	public Level getParent() {
		return parent;
	}

	public boolean hasParent() {
		return (parent != null);
	}

	public DefinitionWrapper getDefinitionWrapper() {
		return new DefinitionWrapper(definition);
	}

	public String getHelpString() {
		return definition.attributeValue("help",
				"No help available for this property.");
	}
}
